package main

import (
	"fmt"
	"gitee.com/tietang/terrace-go/v2/example/moni/dao"
	"gitee.com/tietang/terrace-go/v2/example/moni/dao/ck"
	"gitee.com/tietang/terrace-go/v2/lib/rpc/mo/entity"
	"reflect"
)

type DemoHandler[X any] struct {
}

func (d DemoHandler[X]) Handle(msg X) (res *entity.ResEntity, err error) {
	fmt.Println(msg)
	return
}

type RpcMessage[T any] struct {
	Type    string
	Message T
}

func (r *RpcMessage[T]) GetType() reflect.Type {
	typ := reflect.TypeOf(r.Message)
	return typ
}

func main() {
	//p1 := new(DemoHandler[RpcMessage[string]])
	//demo1(p1)
	demo2()
	//typ := getType(p1)

}
func demo2() {
	ckJvmDao := new(ck.ClickHouseJvmDao)
	//dao.Register("jvm.JvmInfo", ckJvmDao)
	handler := dao.NewHandler(ckJvmDao)
	typ := reflect.TypeOf(handler)
	m, found := typ.MethodByName("Handle")
	fmt.Println(found)
	fmt.Println(m)
	fmt.Println(m.Func.Type().NumIn())
	fmt.Println(m.Func.Type().In(0))
	fmt.Println(m.Func.Type().In(1))
}

func demo1(p1 *DemoHandler[RpcMessage[string]]) {
	val1 := reflect.ValueOf(p1)
	fmt.Println(val1.Elem().Kind())
	typ := val1.Type().Elem()
	m, found := typ.MethodByName("Handle")
	fmt.Println(found)
	fmt.Println(m)
	//size := m.Type.NumIn()
	//for i := 0; i < size; i++ {
	//	atyp := m.Type.In(i)
	//	fmt.Println(atyp)
	//	fmt.Println(atyp.Kind())
	//	fmt.Println(atyp.Name())
	//	fmt.Println(atyp.NumField())
	//	fmt.Println("======")
	//}
	atyp := m.Type.In(1)
	fmt.Println(atyp)
	fmt.Println(atyp.Kind())
	fmt.Println(atyp.Name())
	fmt.Println(atyp.NumField())
	fmt.Println("======")
	f, found := atyp.FieldByName("Message")
	fmt.Println(found)
	fmt.Println(f)
	fmt.Println(f.Type)
	//fmt.Println(v1.Kind())
	//fmt.Println(v1.Elem())
}

func getType(v any) (typ reflect.Type) {
	typ1 := reflect.TypeOf(v)
	m, found := typ1.MethodByName("Handle")
	if !found {
		return
	}
	atyp := m.Type.In(1)
	if atyp == nil {
		return
	}
	f, found := atyp.FieldByName("Message")
	if !found {
		return
	}
	return f.Type
}
